package iblink.adapter.request;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import com.ib.client.Contract;
import com.ib.client.ContractDetails;

import packutil.event.IEvent;
import packutil.idgen.IIdGenerator;
import iblink.adapter.IBClient;
import iblink.event.ContractDetailsResponseEvent;
import iblink.event.IBErrorEvent;
import iblink.event.IBErrorEvent.IbErrorType;
import iblink.exception.IBLinkException;

public class ContractDetailsRequest extends ARequest {

	private final HashSet<IbErrorType> exemptError = new HashSet<IbErrorType>();
	private final Contract contract;

	private List<ContractDetails> contractDetails;

	protected ContractDetailsRequest(IBClient ibClient,
			IIdGenerator requestIdGenerator, Contract contract) {
		super(ibClient, requestIdGenerator);
		this.contract = contract;
		exemptError.add(IbErrorType.NoSecurityDefinitionFound);
	}

	@Override
	protected void execute(IBClient cli, int requestId) {

		cli.reqContractDetails(requestId, contract);
		IEvent response = waitForResponse(exemptError);

		if (response instanceof IBErrorEvent) {

			IBErrorEvent err = ((IBErrorEvent) response);

			// error response, we are only listened for
			// NoSecurityDefinitionFound.. serious bug if we get something else
			if (!IbErrorType.NoSecurityDefinitionFound.equals(err
					.getErrorType())) {
				throw new IBLinkException(
						"Fatal error: Only interested in error type of NoSecurityDefinitionFound, but got back: "
								+ err);
			}
			
			System.out.println(err);

			// got NoSecurityDefinitionFound, we'll treat this as an empty
			// contract details list
			contractDetails = new ArrayList<ContractDetails>();

		} else if (!(response instanceof ContractDetailsResponseEvent)) {

			// got some other response.. serious bug
			throw new IBLinkException(
					"Expecting ContractDetailsResponseEvent, got " + response);

		} else {

			// all is well
			contractDetails = ((ContractDetailsResponseEvent) response)
					.getContractDetails();
		}
	}

	public List<ContractDetails> getContractDetails() {

		if (!executed)
			throw new IBLinkException(
					"Trying to get contract details but request has not yet been executed");

		return contractDetails;
	}
}
